package com.example.treelistviewdemo;

import androidx.annotation.Nullable;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;

import com.google.gson.Gson;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;

public class MainViewModel extends ViewModel {

    public MutableLiveData<List<Node>> nodes = new MutableLiveData<>(new ArrayList<>());

    public MainActivity.NodeAdapter nodeAdapter;

    void create() {
        String json;
        try {
            InputStream stream = MyApplication.getMyContext().getAssets().open("file/data.json");
            BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
            StringBuilder builder = new StringBuilder();
            String data;
            while ((data = reader.readLine()) != null) {
                builder.append(data);
            }
            json = builder.toString();
            reader.close();

            Gson gson = new Gson();
            Node node = gson.fromJson(json, Node.class);

            initialNode(node);

            List<Node> children = new ArrayList<>();
            children.add(node);
            nodes.setValue(children);

        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private void initialNode(Node node) {
        if (node.parent == null) {
            node.top = true;
        }

        if (node.children != null) {
            for (Node child : node.children) {
                child.level = node.level + 1;
                child.parent = node;
                initialNode(child);
            }
        } else {
            node.bottom = true;
        }
    }

    public void itemSelectAction(Node child) {
        if (nodes.getValue() == null) {
            return;
        }

        ArrayList<Node> nodeArrayList = new ArrayList<>(nodes.getValue());

        Node realNode = getRealNode(child);

        if (realNode == null) {
            return;
        }

        if (realNode.fold) {
            expandChildren(realNode, nodeArrayList);
        } else {
            foldChildren(realNode, nodeArrayList);
        }

        for (int i = 0; i < nodeArrayList.size(); i++) {
            Node subNode = nodeArrayList.get(i);
            subNode.index = i;
        }

        nodes.setValue(nodeArrayList);
    }

    /// 展开子节点
    void expandChildren(Node node, List<Node> nodeArrayList) {
        node.fold = false;
        if (node.children != null) {
            nodeArrayList.addAll(node.index + 1, node.children);
        }
    }

    /// 折叠子节点
    void foldChildren(Node node, List<Node> nodeArrayList) {
        node.fold = true;

        if (node.children == null) {
            return;
        }

        nodeArrayList.removeAll(node.children);

        for (Node subNode : node.children) {
            foldChildren(subNode, nodeArrayList);
        }
    }

    /// 获取真实的节点
    @Nullable
    Node getRealNode(Node node) {
        List<Node> _nodes = nodes.getValue();

        if (_nodes == null) {
            return null;
        }

        Optional<Node> optionalNode = _nodes.stream().filter(new Predicate<Node>() {
            @Override
            public boolean test(Node element) {
                return element.id.equals(node.id);
            }
        }).findFirst();

        return optionalNode.orElse(null);

    }

    void selectionAction(Node node) {
        Node realNode = getRealNode(node);

        if (realNode == null) {
            return;
        }

        selectChildren(realNode, null);
        selectParent(realNode);
        nodes.setValue(nodes.getValue());
    }

    /// 处理子节点的选中状态
    private void selectChildren(Node node, @Nullable Node parent) {
        if (parent != null) {
            node.selection = parent.selection;
        } else if (node.selection == SelectionStatus.all) {
            node.selection = SelectionStatus.none;
        } else {
            node.selection = SelectionStatus.all;
        }
        if (node.children == null) {
            return;
        }
        for (Node child : node.children) {
            selectChildren(child, node);
        }
    }

    /// 处理父节点的选中状态
    void selectParent(Node node) {
        if (node.parent == null || node.parent.children == null) {
            return;
        }

        boolean any = node.parent.children.stream().anyMatch(new Predicate<Node>() {
            @Override
            public boolean test(Node element) {
                return element.selection == SelectionStatus.any || element.selection == SelectionStatus.all;
            }
        });

        boolean all = node.parent.children.stream().allMatch(new Predicate<Node>() {
            @Override
            public boolean test(Node element) {
                return element.selection == SelectionStatus.all;
            }
        });

        if (all) {
            node.parent.selection = SelectionStatus.all;
        } else if (any) {
            node.parent.selection = SelectionStatus.any;
        } else {
            node.parent.selection = SelectionStatus.none;
        }

        selectParent(node.parent);
    }
}
